package string_0923;

import java.util.Arrays;

/**
 * 字符串的不可变性：
 * 当一个字符串的对象产生之后，他的内容就无法修改，这称之为字符串对象的不可变性
 * ps:String类所有修改字符的方法，都会产生新的字符对象，并不会影响原字符串对象
 * ！！！由于字符串对象的不可变性，因此直接使用字符串对象进行+=操作的时候产生大量的临时对象，浪费内存
 *
 * 原因：
 * 1.方便实现字符串对象池，如果String可变，那么对象池就需要考虑写时拷贝的问题了
 * 2.不可变对象是线程安全的
 * 3.不可变对象更方便缓存hash code,作为key时可以更高效的保存到HashMap
 */
public class StringNoChange {
    public static void main(String[] args) {
//        //不可变的变量，就叫常量
//        final int a=10;
//        //这里指的是不可变性是指内容不可变，而不是字符串的引用
//        String str="hello";//字符串的引用（指向）发生改变
//        str+="world";//+表示字符串的拼接
//        System.out.println(str);
        String str="abc";
        char[]value={'a','b','c'};
        fun(str,value);//数组引用abc中a会被g修改
        //abc
        System.out.println(str);
        //gbc
        System.out.println(Arrays.toString(value));

    }
    private static void fun(String str,char[]value){
        str="gbc";
        value[0]='g';
    }
}
/**
 * public final class String
 *private final char value[];//value字符数组是真正保存字符串内容的
 * 经典面试题：怎么理解字符串不可变，如何做到内容不可修改
 *final修饰引用的数据类型的变量，不能改变的是这个引用的指向不变，至于引用的对象内部如何变化，是可以的
 * （补充：被final修饰的变量天然线程安全）
 * 因此字符串对象内容不可变与final修饰没啥关系，final只能确保value的指向不变！
 * 字符串对象的内容不可变，本质在于private封装。
 * 出了String这个类，外部根本无法直接操作value这个字符数组，除非提供setter和getter方法
 *
 */

